Skip to content

feat(gallery): resolve breakpoints from config - #31519

Open
brandyscarney wants to merge 7 commits into
FW-7285-3-grid-colfrom
FW-7285-4-gallery
Open

brandyscarney wants to merge 7 commits into
FW-7285-3-grid-colfrom
FW-7285-4-gallery

Conversation

@brandyscarney

Copy link
Copy Markdown
Member

The gallery now uses the shared screen breakpoints and respects the screenBreakpoints config. Breakpoints are still matched against the gallery's own width rather than the width of the screen, which is now noted in the properties.

@brandyscarney
brandyscarney added this pull request to stack #31503 October 1, 2026 19:14
@vercel

vercel Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
ionic-framework Ready Ready Preview Oct 12, 2026 9:14pm UTC

Request Review

@github-actions github-actions Bot added the package: core @ionic/core package label Oct 1, 2026
@brandyscarney
brandyscarney marked this pull request as ready for review October 2, 2026 13:50
@brandyscarney
brandyscarney requested a review from a team as a code owner October 2, 2026 13:50
@brandyscarney
brandyscarney requested review from thetaPC and removed request for a team October 2, 2026 13:50

@ShaneK ShaneK left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me! The only real issue is a gallery narrower than a configured xs above 0 ending up with no column count, which has a one-line fix. The rest are just nits.

providedValue === undefined || sanitizedProvided === undefined ? sanitizedDefault : sanitizedProvided;

if (resolved !== undefined && width >= BREAKPOINTS[bp]) {
if (resolved !== undefined && width >= breakpoints[bp]) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (resolved !== undefined && width >= breakpoints[bp]) {
if (resolved !== undefined && (bp === 'xs' || width >= breakpoints[bp])) {

Now that xs comes from config it can be above 0, and a gallery narrower than it won't match anything here. The DEFAULT_COLUMNS fallback runs through this same loop, so we end up setting --internal-gallery-columns to "undefined", which the 2 fallback in the stylesheet can't catch since the variable is set. With screenBreakpoints: { xs: 400 } and a 300px gallery, it collapses to one column with every item on its own row, and masonry skips layout.

Since the gallery measures its own width, I think one in a card or sidebar could hit this pretty easily. Letting xs always match keeps the behavior from when it was hardcoded to 0, and with it that case resolves to the xs value while the existing specs and breakpoints e2e still pass. Could you add a spec case for it too, something like xs: 400 at a width of 300?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can update it but this seems weird no? Shouldn't one breakpoint always be 0? Do we add an xxs that must be 0, or require xs to be 0? Should I make a follow-up for this?

Fix: 085bb4b

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure, this is just a weird edge case that could come up I noticed. I think it's extremely unlikely, but 🤷‍♂️

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default of 0 is enough, I don't think we need a follow-up. If an app moves xs above 0, what happens below it is on the app. A quick check on how other frameworks handle a raised smallest breakpoint could be good to review, though, in case there's a convention worth matching.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided to remove the xs breakpoint from the screenBreakpoints config. With the way the new CSS is written, there would be no way to target the screen size under the xs breakpoint if it was larger than 0. Additionally, adding this code above just made it so that them setting it to anything above 0 was ignored for smaller breakpoints anyway: 89fbc37

Comment thread core/src/components/gallery/test/breakpoints/gallery.e2e.ts
Comment thread core/src/components/gallery/test/breakpoints/gallery.e2e.ts Outdated
Comment thread core/src/components/gallery/gallery.tsx Outdated

@thetaPC thetaPC left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, as long as we can address FW-7285 soon

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FW-7582 isn't in FW-7285's follow-up tickets, and I think this stack is where it belongs. Could it land as a stacked PR on top of split-pane once we decide the behavior?

  • Keeping the per-breakpoint default fill makes { md: 5 } resolve to 2, 3, 5, 6, 8, 10, so the 5 stops applying above md
  • feat(grid, col): resolve breakpoints from config #31518 resolves col.size = { md: 6 } with resolveBreakpointMap, which carries the value upward, so col and gallery would treat the same breakpoint map shape differently once the stack merges

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll add it as a follow-up ticket, but I don't think it belongs in this one. This ticket changes where the breakpoints come from, making them respect the screenBreakpoints config, not how components cascade values across them. That behavior is not changed by any of my PRs.

It's also not just a decision for gallery. In ion-col, size, order and offset use resolveBreakpointMap and cascade, while the padding variables do not. The gallery resolves columns and gap in JS like size but doesn't cascade.

Worth noting the example in FW-7582 uses gap, which is spacing, and spacing doesn't cascade anywhere else in the framework either. How cascading should work for both component properties and CSS variables is worth deciding on that ticket.

providedValue === undefined || sanitizedProvided === undefined ? sanitizedDefault : sanitizedProvided;

if (resolved !== undefined && width >= BREAKPOINTS[bp]) {
if (resolved !== undefined && width >= breakpoints[bp]) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default of 0 is enough, I don't think we need a follow-up. If an app moves xs above 0, what happens below it is on the app. A quick check on how other frameworks handle a raised smallest breakpoint could be good to review, though, in case there's a convention worth matching.

This branch was successfully deployed

1 active deployment
Preview — cfe3ecf4 Deployed Oct 12, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

package: core @ionic/core package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants